Матч
431, Сумма и произведение (SumAndProduct)
Дивизион 2,
Уровень 3
Список неотрицательных чисел
называется удовлетворительным, если их сумма равна s, а произведение p.
Найти удовлетворительный список с наименьшим количеством элементов и вернуть
его длину. Если такого списка не существует, вернуть -1.
Класс: SumAndProduct
Метод: int
smallestSet(int s, int p)
Ограничения: 1 £ s, p £ 109.
Вход. Два числа s и p.
Выход. Наименьшее количество элементов в удовлетворительном списке.
Если такого списка не существует, вернуть -1.
Пример входа
s |
p |
10 |
10 |
5 |
100 |
100 |
1000000000 |
Пример выхода
1
-1
9
РЕШЕНИЕ
математика
В задаче следует найти наименьшее
n, для которого существуют такие x1, x2, …, xn,
что
Рассмотрим,
какие значения может принимать произведение x1
* x2 * … * xn для заданных n и s.
Если n = 1, то решением будет x1 = s = p. При n = 2
сумма x1 + x2 = s, произведение равно x1
* x2 = x1 * (s – x1).
Рассмотрим, какие значения может принимать произведение. Решим уравнение x * (s
– x) = p или x2 – s * x + p = 0. Дискриминант уравнения
равен D = s2 – 4 * p. Уравнение имеет решение при D ³ 0 или p £ s2 / 4 . Если p ³ 0, то решения
x1,2 =
будут
неотрицательными. Таким образом, с помощью двух действительных чисел, сумма
которых равна s, можно получить любое произведение от 0 до s2 / 4. При этом наибольше произведение s2 / 4 можно получить при x1 = x2 = s / 2.
Лемма. Если сумма n чисел
равна s, то их максимально
произведение равно (s / n)n
и достигается при x1 = x2 = … = xn = s / n.
Если предположить противное, то
найдется наименьшее m = xi и наибольшее M = xj
среди этих чисел. Заменим m и M на числа (m + M) / 2 и (m + M)
/ 2. В таком случае произведение x1
* x2 * … * xn увеличится.
Доказательство. Докажем неравенство . Имеем: , , что верно так как по предположению m и M не равны между собой.
Теорема. Если сумма n чисел
равна s, то их произведение может
принимать любое значение от 0 до (s /
n)n.
Согласно лемме, наибольшее
значение (s / n)n
достигается при x1 = x2 = … = xn = s / n. Осталось показать, что достигается и
любое другое произведение p, 0 £ p £ (s / n)n.
Доказательство проведем конструктивно.
Возьмем b = p / (s / n)n-2.
Очевидно, что 0 £ b £ (s / n)2.
Исходя из выше доказанного, существуют такие x1 и x2,
что x1 + x2 = 2 * s / n, x1 * x2 = b £ (2 * s / n)2 / 4 = (s / n)2.
Добавим значения x3 = x4 = … = xn = s / n чтобы получить требуемые n чисел: x1 + x2
+ … + xn = 2 * s / n
+ (n – 2) * s / n = s, x1
* x2 * … * xn = b * (s / n)n-2
= p.
Таким образом, алгоритм решения
задачи состоит в следующем:
1. Если s = p, то вернуть 1.
2. Последовательно перебираем n = 2, 3, …, s. Как только станет p £ (s / n)n, возвращаем n.
3. Если на втором шаге решение не
найдено, то возвращаем -1.
Пример. Найти n = 5 чисел, сумма которых равна s = 10,
а произведение p = 30.
Такие числа существуют, так как p ≤ (s / n)n = (10 / 5)5 = 32. Выберем такие x1 и x2, что x1 + x2 = 2 * s / n = 2 * 10 / 5 = 4, а их произведение
равно b = p / (s / n)n-2 = 30 / (10 / 5)3 = 30 / 8 = 15 / 4. Такие числа
существуют согласно лемме. Выберем x3
= x4 = x5 = s / n = 10 / 5 = 2.
Указанные пять чисел и будут являться ответом.
ПРОГРАММА
#include <stdio.h>
#include <math.h>
class SumAndProduct
{
public:
int smallestSet(int
s, int p)
{
int n;
if (s == p) return
1;
for(n = 2; n <= s; n++)
if (pow(1.0 * s / n, 1.0 * n) >= p) return n;
return -1;
}
};